﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Management;
using YunLuPos.Printer;

namespace YunLuPos.Printer
{
    public class USBPrinter : PrintBase
    {

        const uint GENERIC_READ = 0x80000000;
        const uint GENERIC_WRITE = 0x40000000;
        const uint FILE_ATTRIBUTE_NORMAL = 0x80;

        [DllImport("kernel32.dll")]
        public static extern int CreateFile(
          string lpFileName,
          uint dwDesiredAccess,
          int dwShareMode,
          int lpSecurityAttributes,
          int dwCreationDisposition,
          uint dwFlagsAndAttributes,
          int hTemplateFile
          );

        [DllImport("kernel32.dll")]
        public static extern bool WriteFile(
          int hFile,
          byte[] lpBuffer,
          int nNumberOfBytesToWrite,
          ref int lpNumberOfBytesWritten,
          int lpOverlapped
          );

        [DllImport("kernel32.dll")]
        public static extern bool DefineDosDevice(
        int dwFlags,
        string lpDeviceName,
        string lpTargetPath);

        [DllImport("kernel32.dll")]
        public static extern bool CloseHandle(
          int hObject
          );
        [DllImport("kernel32.dll")]
        public static extern bool ReadFile(
          int hFile,
          byte[] lpBuffer,
          int nNumberOfBytesToRead,
          ref int lpNumberOfBytesRead,
          int lpOverlapped
          );

        private List<Int32> handles = new List<int>();

        public override bool Dispose()
        {
            foreach (Int32 handle in handles)
            {
                CloseHandle(handle);
            }
            handles = new List<int>();
            return true;
        }

        public override bool initPrinter()
        {
            var win32DeviceClassName = "Win32_USBHub";
            var query = string.Format("select * from {0}", win32DeviceClassName);
            StringBuilder sb = new StringBuilder();

            using (var searcher = new ManagementObjectSearcher(query))
            {
                foreach (ManagementObject disk in searcher.Get())
                {
                    string PNPDeviceID = disk["PNPDeviceID"] as String;
                    int iHandle = CreateFile("\\\\.\\" + PNPDeviceID.Replace('\\', '#') + "#{A5DCBF10-6530-11D2-901F-00C04FB951ED}"
                    , 0x80000000 | 0x40000000, 0, 0, 3, 0, 0);
                    if (iHandle != -1)
                    {
                        handles.Add(iHandle);
                    }
                }
            }
            if (handles.Count <= 0)
            {
                return false;
            }
            return true;
        }

        public override bool NewRow()
        {
            byte[] temp = new byte[] { 0x0A };
            return write(temp);
        }

        public override bool open()
        {
            return true;
        }

        public override bool write(byte[] b)
        {
            foreach (Int32 handle in handles)
            {
                int i = 0;
                WriteFile(handle, b, b.Length, ref i, 0);
            }
            return true;
        }
    }
}
